function MoveUp(oActive)
{
	if (oActive)
	{		
		if (oActive.parentElement.previousSibling)
		{
			// if cell spans both columns or the next rows cell spans both columns move the whole row down
			if ((oActive.parentElement.cells.length == 1) || (oActive.parentElement.previousSibling.cells.length == 1))
			{
				// swap the nodes in the xml
				MoveUpAdjacentXml(GetRowNode(oActive.name));
				
				// swap the nodes in the html
				oActive.parentElement.swapNode(oActive.parentElement.previousSibling);
			}
			else
			{
				// swap the nodes in the xml
				SwapUpBottomXml( GetCellNode(oActive.name) );
				
				PurgeEmptyRowsXml();

				// swap the nodes in the html
				oActive.swapNode(oActive.parentElement.previousSibling.cells[oActive.cellIndex]);
				
				PurgeEmptyRowsHtml();
			}
		}
	}
}


function MoveDown(oActive)
{
	if (oActive)
	{
		if (oActive.parentElement.nextSibling)  //if it is not the last row
		{
			// if cell spans both columns or the next rows cell spans both columns move the whole row down
			if ((oActive.parentElement.cells.length == 1) || (oActive.parentElement.nextSibling.cells.length == 1))
			{
				// swap the nodes in the xml
				MoveDownAdjacentXml(GetRowNode(oActive.name));
				
				// swap the nodes in the html
				oActive.parentElement.swapNode(oActive.parentElement.nextSibling);			
			}
			else
			{
				// swap the nodes in the xml
				var oNode = GetCellNode(oActive.name);
				var index = oNode.nextSibling ? 0 : 1;
				SwapUpBottomXml(oNode.parentNode.nextSibling.childNodes[index]);
				
				PurgeEmptyRowsXml();
				
				// swap the nodes in the html
				oActive.swapNode(oActive.parentElement.nextSibling.cells[oActive.cellIndex]);
				
				PurgeEmptyRowsHtml();
			}
		}
	}
}

function MoveLeft(oActive)
{
	if (oActive)
	{
		if (oActive.previousSibling) //don't move if it is the last one to the left
		{
			// only pertains to cells that don't span both columns
			if (oActive.parentElement.cells.length > 1)
			{
				// swap the nodes in the xml
				MoveUpAdjacentXml(GetCellNode(oActive.name));
				
				// swap the nodes in the html
				oActive.swapNode(oActive.previousSibling);
			}
		}
	}
}


function MoveRight(oActive)
{	
	if (oActive)
	{
		if (oActive.nextSibling)
		{
			// only pertains to cells that don't span both columns
			if (oActive.parentElement.cells.length > 1)
			{
				// swap the nodes in the xml
				MoveDownAdjacentXml(GetCellNode(oActive.name));

				// swap the nodes in the html
				oActive.swapNode(oActive.nextSibling);				
			}
		}
	}
}


// swaps node with previous node in xml
// used for left and up
function SwapUpBottomXml(oNode)
{	
	var oPrevParentNode	= oNode.parentNode.previousSibling;
	var oNextParentNode	= oNode.parentNode;
	var index = oNode.nextSibling ? 0 : 1; //if there is one next means it is the first one
	
	var oNodeTopInsert = oPrevParentNode.childNodes[index+1]; //will be null when index = 1
	var oNodeBottomInsert = oNextParentNode.childNodes[index+1]; //will be null when index = 1
	
	oPrevParentNode.insertBefore(oNextParentNode.removeChild(oNextParentNode.childNodes[index]), oNodeTopInsert);
	oNextParentNode.insertBefore(oPrevParentNode.removeChild(oPrevParentNode.childNodes[index]), oNodeBottomInsert);
}

// swaps node with previous node in xml
// used for left and up
function MoveUpAdjacentXml(oNode)
{
	var oParentNode	= oNode.parentNode;
	var oPrevRef	= oNode.previousSibling;
	var oSwapNode	= oParentNode.removeChild(oNode); //removes the active
	oParentNode.insertBefore(oSwapNode, oPrevRef); //inserts the active above
}


// swaps node with next node in xml
// used for right and down
function MoveDownAdjacentXml(oNode)
{
	var oParentNode = oNode.parentNode;
	var oSwapNode	= oParentNode.removeChild(oNode.nextSibling); //removes the active next
	oParentNode.insertBefore(oSwapNode, oNode); //insert the active next before the active
}


// removes all rows containing only empty cells from xml
//
function PurgeEmptyRowsXml()
{
	var oRows = oPreviewXml.selectNodes("/preview/rows/row[not(cell[0]/@name) and not(cell[1]/@name)]");

	// if we find one, strip it and jump out since there will never be more than one
	//
	for (var i = 0; i < oRows.length; i++)
	{
		oRows[i].parentNode.removeChild(oRows[i])
		return;
	}
}


// removes all rows containing only empty cells from html
//
function PurgeEmptyRowsHtml()
{
	var i;
	var oRow;
	var iRowsLen = rowsContent.rows.length;

	for (i = 0; i < iRowsLen; i++)
	{
		oRow = rowsContent.rows[i];
		
		// if we find one, strip it and jump out since there will never be more than one
		//
		if (oRow.cells[0].innerHTML == "") 
		{
			if (oRow.cells[1]) //if there is more than one column
			{	
				if (oRow.cells[1].innerHTML == "") 
				{
					oRow.parentElement.deleteRow(oRow.rowIndex);
					return;
				}
			}
			else
			{
				oRow.parentElement.deleteRow(oRow.rowIndex);
				return;				
			}
		}
	}
}